package jwt

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	login_req "go-small-shopping/entity/dto"
	"time"
)

const KEY = "1066e1e8a49275706e9e8e88967f63ebae7c4629543e53c769c448706ff5b614"

type CustomClam struct {
	*jwt.StandardClaims
	User *login_req.LoginUser
}

func GenerateJWT(user *login_req.LoginUser) (string, error) {
	exp := time.Now().Add(time.Hour * 2).Unix()
	claim := CustomClam{
		User: user,
		StandardClaims: &jwt.StandardClaims{
			ExpiresAt: exp,
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
	secretKey := []byte(KEY)

	tokenString, err := token.SignedString(secretKey)

	if err != nil {
		return "", err
	}
	return tokenString, nil
}

func ValidateJWT(tokenString string) (*CustomClam, error) {
	secretKey := []byte(KEY)

	token, err := jwt.ParseWithClaims(tokenString, &CustomClam{}, func(token *jwt.Token) (interface{}, error) {
		return secretKey, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*CustomClam); ok && token.Valid {
		return claims, nil
	}
	return nil, fmt.Errorf("invalid token")
}

func ParseToken(tokenString string) (*login_req.LoginUser, error) {
	secretKey := []byte(KEY)
	token, err := jwt.ParseWithClaims(tokenString, &CustomClam{}, func(token *jwt.Token) (interface{}, error) {
		return secretKey, nil
	})

	if claims, ok := token.Claims.(*CustomClam); ok && token.Valid {
		return claims.User, nil
	}
	return nil, err
}
